package com.bluexmicro.module_componment.file

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.view.*
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.asLiveData
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSnapHelper
import androidx.recyclerview.widget.RecyclerView
import com.bluexmicro.module_componment.R
import com.bluexmicro.module_componment.databinding.FragmentInnerFilesBinding
import kotlinx.coroutines.launch
import java.math.BigInteger


/**
 *  before android 10: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 *  Android 10: android:requestLegacyExternalStorage="true"
 *  Android 11: <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
 */
class FilesFragment : Fragment() {

    private var mBinding: FragmentInnerFilesBinding? = null

    private val viewModel by activityViewModels<FileViewModel>()

    private val fileAdapter = FileAdapter()
    private val pathAdapter = DirAdapter()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return FragmentInnerFilesBinding.inflate(inflater, container, false).run {
            mBinding = this
            root
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mBinding = null
    }

    private var permissionLauncher: ActivityResultLauncher<Intent>? = null
    private val snapHelper = LinearSnapHelper()
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        fileAdapter.needGrantPermission = !checkPermission()

        permissionLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                fileAdapter.needGrantPermission = !checkPermission()
            }

        mBinding?.apply {
            setupFileView()
            setupAddressView()


            chooseBtn.setOnClickListener {
                viewModel.selectedFile.value?.apply {
                    val address = try {
                        BigInteger(viewModel.payload.value, 16)
                    } catch (ignore: Exception) {
                        null
                    }
                    viewModel.choose(this, address)
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        //拦截返回事件，当前目录不是根目录时，返回上一级目录
        requireView().apply {
            isFocusableInTouchMode = true
            requestFocus()
            setOnKeyListener { _, keyCode, event ->
                val dispatch =
                    event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK
                if (dispatch) {
                    if (!viewModel.loadParent()) {
                        viewModel.onBackEvent()
                    }
                }
                dispatch
            }
        }
    }
    ///////////////////////////////////////////////////////////////////////////
    // 文件目录
    ///////////////////////////////////////////////////////////////////////////

    private fun FragmentInnerFilesBinding.setupFileView() {

        fileListView.apply {
            layoutManager = LinearLayoutManager(context)
            setHasFixedSize(true)
            adapter = fileAdapter
        }
        pathListView.apply {
            layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
            snapHelper.attachToRecyclerView(this)
            setHasFixedSize(false)
            adapter = pathAdapter
        }

        lifecycleScope.launch {
            viewModel.data.collect {
                fileAdapter.submitList(it.currentFiles)
                pathAdapter.submitList(it.folderStacks)
                emptyIcon.visibility = if (it.currentFiles.isEmpty()) View.VISIBLE else View.GONE
            }
        }

        viewModel.selectedFile.asLiveData().observe(viewLifecycleOwner) {
            fileAdapter.selectedFiles = if (it != null) mutableListOf(it) else emptyList()
        }

        fileAdapter.setOnItemClick {
            if (fileAdapter.needGrantPermission) {
                requestPermission()
                return@setOnItemClick
            }
            val file = fileAdapter.currentList[it]
            if (file == com.bluexmicro.module_componment.file.root || file.isDirectory) {
                viewModel.loadFolder(file)
            } else {
                viewModel.selectedFile.value = file
            }
        }

        pathAdapter.setOnItemClick {
            viewModel.loadFolder(pathAdapter.currentList[it])
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // 地址
    ///////////////////////////////////////////////////////////////////////////

    private fun FragmentInnerFilesBinding.setupAddressView() {
        addressInput.setEndIconActivated(true)
        addressInput.isEndIconVisible = true
        addressInput.setEndIconDrawable(R.drawable.ic_baseline_backspace_24)
        addressInput.setEndIconOnClickListener {
            viewModel.backspace()
        }

        val keys: MutableList<TextView> = mutableListOf(
            btn0,
            btn1,
            btn2,
            btn3,
            btn4,
            btn5,
            btn6,
            btn7,
            btn8,
            btn9,
            btnA,
            btnB,
            btnC,
            btnD,
            btnE,
            btnF
        )
        for (key in keys) {
            key.setOnClickListener {
                viewModel.appendNumber(key.text.toString())
            }
        }

        withAddressSwitch.setOnCheckedChangeListener { _, isChecked ->
            viewModel.setWithAddress(isChecked)
        }

        lifecycleScope.launch {
            viewModel.withAddress.collect {
                if (withAddressSwitch.isChecked != it) {
                    withAddressSwitch.isChecked = it
                }
                val show = if (it) View.VISIBLE else View.GONE
                numKeyboard.visibility = show
                addressInput.visibility = show
            }
        }

        lifecycleScope.launch {
            viewModel.payload.collect {
                addressEt.setText(it)
            }
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // 权限
    ///////////////////////////////////////////////////////////////////////////

    private val permissions = arrayOf(
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    )

    private fun checkPermission(): Boolean {
        return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
            ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.READ_EXTERNAL_STORAGE
            ) == PackageManager.PERMISSION_GRANTED
        } else {
            Environment.isExternalStorageManager()
        }
    }

    private fun requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            //Android10的文件管理的适配
            val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
            intent.data = Uri.parse("package:" + requireContext().packageName)
            permissionLauncher?.launch(intent)
        } else {
            val sp = requireContext().getSharedPreferences("easy file picker", Context.MODE_PRIVATE)
            val firstRequest = sp.getBoolean("firstRequest", true)
            if (firstRequest) {
                ActivityCompat.requestPermissions(requireActivity(), permissions, 100)
                sp.edit().putBoolean("firstRequest", false).apply()
            } else {
                val should = permissions.all {
                    shouldShowRequestPermissionRationale(it)
                }
                if (should) {
                    ActivityCompat.requestPermissions(requireActivity(), permissions, 100)
                } else {
                    val intent = Intent()
                    intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                    intent.data = Uri.parse("package:" + requireContext().packageName)
                    startActivity(intent)
                }
            }
        }
    }


}